package org.xiaov.framework.util;

import cn.hutool.core.bean.BeanUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.xiaov.framework.component.SpringContext;
import org.xiaov.framework.exception.BizException;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 描述：
 * </p>
 *
 * @author xiaovcloud
 * @since 2021/10/6 22:09
 */
public class RedisUtils {

    private static final RedisTemplate<String, String> REDIS_TEMPLATE =
            SpringContext.getBean("stringRedisTemplate", RedisTemplate.class);

    // =============================common============================

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     */
    public static void expire(String key, long time) {
        if (time > 0) {
            REDIS_TEMPLATE.expire(key, time, TimeUnit.SECONDS);
        }
        throw new BizException("指定缓存失效");
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public static Long getExpire(String key) {
        return REDIS_TEMPLATE.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public static Boolean hasKey(String key) {
        try {
            return REDIS_TEMPLATE.hasKey(key);
        } catch (Exception e) {
            throw new BizException("查询缓存异常", e);
        }
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    public static void del(String... key) {
        if (key != null && key.length > 0) {
            REDIS_TEMPLATE.delete(Arrays.asList(key));
        }
    }

    /**
     * 获取数据库中所有的key
     *
     * @return Set<String>
     */
    public static Set<String> getKeys() {
        return REDIS_TEMPLATE.keys("*");
    }

    /**
     * 删除数据库中所有的数据
     */
    public static void deleteAll() {
        Set<String> keys = getKeys();
        if (BeanUtil.isNotEmpty(keys)) {
            del(keys.toArray(new String[0]));
        }
    }

    /**
     * 获取redis中所有的值
     *
     * @return map
     */
    public static Map<String, String> getKeyAndValue() {
        Set<String> keys = getKeys();
        if (BeanUtil.isEmpty(keys)) {
            return null;
        }
        HashMap<String, String> map = new HashMap<>(16);
        for (String key : keys) {
            String value = get(key);
            map.put(key, value);
        }
        return map;
    }

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public static String get(String key) {
        return key == null ? null : REDIS_TEMPLATE.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     */
    public static void set(String key, String value) {
        try {
            REDIS_TEMPLATE.opsForValue().set(key, value);
        } catch (Exception e) {
            throw new BizException("值放入redis异常", e);
        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     */
    public static void set(String key, String value, long time) {
        try {
            if (time > 0) {
                REDIS_TEMPLATE.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
        } catch (Exception e) {
            throw new BizException("值放入redis异常", e);
        }
    }

}
